import BaseFormWidget from './BaseFormWidget.js';
import {
    getOpt
} from "../tools.js";
import {
    updateSelectOptions
} from '../tools.js';


var template = require('./templates/CheckboxListWidget.mustache');

/*
 * A drop-in replacement for SelectWidget with multiple: true
 *
 *
 * Features :
 *  - single or multiple item selector
 *  - optionaly supports displaying only a subset of the options
 *   (configurable filter function).
 * - optionaly togglable modes (view/edit).
 *
 *  Triggers on value selection (two different events to allow two way of event bindings):
 *  - "finish", field_name, field_value 
 *  - "finish:field_name", field_value
 * 
 * Support following options
 *
 *   :param str title: The field label
 *   :param str description:
 *   :param str field_name:
 *   :param list options: The options to render list of objects
 *   :param list value: the values to select
 *   :param str id_key: The key of the options used as option's "value", default is "value"
 *   :param bool editable: is this read-only ?
 *   :param bool togglable: (default: false): enable the togglable view/edit mode
 *   :param str removeItemConfirmationMsg: (default: undefined) if set, prompt
 *      for confirmation when unchecking an item.
 *   :param optionFilter: an optional function to filter the <option> to be shown
 *     * Returns true if the option should be offered.
 *     * Takes two params:
 *         * obj option: The option to be evaluated for display
 *   :param layout: which CSS layout to use for checkbox list ? ("two_cols", "three_cols"…),
 *     defaults to nothing special, which means vertical list rendering.
 *   :param noOptionMessage: which message to display when no option is available
 */
const CheckboxListWidget = BaseFormWidget.extend({
    template: template,
    ui: {
        checkboxes: 'input[type=checkbox]',
        toggleEdit: 'button.edit',
    },
    events: {
        'click @ui.checkboxes': 'onClick',
        'click @ui.toggleEdit': 'onToggleEdit',
    },
    getCurrentValues: function () {
        var checkboxes = this.$el.find('input[type=checkbox]:checked');
        var res = [];
        _.each(checkboxes, function (checkbox) {
            res.push($(checkbox).attr('value'));
        });
        return res;
    },
    onClick: function (event) {
        this.options.value = this.getCurrentValues();
        let continueEvent;
        let removeItemConfirmationMsg = this.getOption('removeItemConfirmationMsg')
        if (!event.target.checked && removeItemConfirmationMsg) {
            continueEvent = window.confirm(removeItemConfirmationMsg);
        } else {
            continueEvent = true;
        }

        if (continueEvent) {
            const values = this.getCurrentValues();
            this.triggerFinish(values);
        } else {
            event.preventDefault();
        }
        this.render();
    },
    onToggleEdit: function (event) {
        this.editing = !this.editing;
        this.render();
    },
    filterOptions(options) {
        let currentValues = this.getOption('value');
        let optionFilter = this.getOption('optionFilter');
        let currentOption = undefined;
        if (optionFilter) {
            if (currentValues.length > 0) {
                currentOption = options.find(
                    x => String(x.id) === String(currentValues[0])
                );
            }
            return options.filter(x => optionFilter(x, currentOption));
        } else {
            return options;
        }
    },
    templateContext: function () {
        var id_key = getOpt(this, 'id_key', 'id');
        var options = this.filterOptions(this.getOption('options'));

        var current_values = this.getOption('value');
        let editing;
        updateSelectOptions(options, current_values, id_key);
        var selectedOptions = options.filter(x => x.selected);

        let togglable = getOpt(this, 'togglable', false);
        if (togglable) {
            editing = this.editing == undefined ? false : this.editing;
        } else {
            editing = getOpt(this, 'editable', true);
        }

        let result = this.getCommonContext();
        let other = {
            options: options,
            selectedOptions: selectedOptions,
            editing: editing,
            togglable: togglable,
            layout: getOpt(this, 'layout', null),
            noOptionMessage: getOpt(this, 'noOptionMessage', ""),
        };
        result = Object.assign(result, other);
        return result;
    }
});
export default CheckboxListWidget;